<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2024/8/12
 * Time: 16:53
 */

namespace app\common\lib;


use app\exception\IndexException;

class VolcanoTts
{
    protected $appid;

    protected $cluster;

    protected $secretKey;

    protected $accessToken;

    protected static $instance;

    public function __construct()
    {
        $this->appid = '9361166377';
        $this->cluster = 'volcano_tts';
        $this->accessToken = '6HmE0Vyhku1oGr7g_cY4uvhiTwu2_zBI';
        $this->secretKey = 'YL9GQYsCcNqrxN-_UGQ535W-8gDDssmQ';
    }


    public static function getInstance()
    {
        //        if(is_object(self::$instance)){
//            return self::$instance;
//        }


        return new self();
    }

    /**
     * 文本语音合成
     * @param $text
     * @param array $option
     * @return array
     * @throws \Throwable
     */
    public function textToVoice($text,$option=[])
    {
        $param = [
            'app'   => [
                'appid'=>$this->appid,
                'token'=> Common::randString(12,1),
                'cluster'=>'volcano_tts'
            ],
            "user"=>[
                "uid"=> Common::randString(12,1)
            ],
            "audio"=>[
                "voice_type"=>$option['speaker'],
                "encoding"=>$option['audio_type']??"mp3",
                "speed_ratio"=> floatval($option['speed']??'1.0'),
                "volume_ratio"=>floatval($option['volume']??'1.0'),
                "pitch_ratio"=>1.0,
            ],
            "request"=>[
                "reqid"=> Common::getRequestId(),
                "text"=> $text,
                "text_type"=>"plain",
                "operation"=>"query",
                "with_frontend"=>1,
                "frontend_type"=>"unitTson"
            ],
        ];
        $headers = [
            'Authorization'=>'Bearer;'.$this->accessToken,
        ];

        $result = Guzzle::post('https://openspeech.bytedance.com/','api/v1/tts',$param,$headers,'json');
        if($result==false){
            throw new IndexException(4020,Guzzle::getError());
        }
        if($result['code']==3000){
            $content = file_get_contents('data:audio/mpeg;base64,'.$result['data']);

            //var_dump($result['addition']);
            $frontend = json_decode($result['addition']['frontend'],true);
            $subTitles = [];
            $subTitle = [];
            $words = [];
            foreach($frontend['words'] as $word){
                if($subTitle){
                    $word['unit_type']=='text' && $subTitle['content'] .= $word['word'];
                    $subTitle['end'] = round($word['end_time']*1000);
                }else{
                    $word['unit_type']=='text' && $subTitle['content'] = $word['word'];
                    $subTitle['start'] = round($word['start_time']*1000);
                    $subTitle['end'] = round($word['end_time']*1000);
                }

                if($word['unit_type']=='mark'){
                    $subTitles[] = $subTitle;
                    $subTitle = [];
                }
                $words[] = [
                    'start'=>round($word['start_time']*1000),
                    'end'=>round($word['end_time']*1000),
                    'content'=>$word['word'],
                ];
            }
            return ['srt_address_data'=>$words,'content'=>$content];
        }else{
            $code = $contents['code']??4020;
            $desc = $contents['message']??'生成失败';
            throw new IndexException($code,$desc);
        }
    }
}